import store from './store'
import axios from 'axios'
import qs from 'qs'
import controls from './controls/controls'
import config from '../config'
import { useRouter } from 'vue-router'
import { ref } from 'vue'
import settings from './settings/settings'

export default {
    routerf: () => useRouter(),
    settings,
    store,
    wait(n) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve()
            }, n * 1000);
        })
    },
    async requestData(path = '', data = {}, method = 'post', loading = true) {
        method = method.toLocaleLowerCase()
        const handle = async (url, data) => {
            console.log(`请求 - 开始`, path, method, data)
            let re
            if (method == 'get') {
                re = await axios.get(config.apiPrefix + url + `?${qs.stringify(data)}`, {
                    headers: {
                        token: store.getItem('userData_token')
                    }
                })
            } else {
                re = await axios.post(config.apiPrefix + url, data, {
                    headers: {
                        token: store.getItem('userData_token')
                    }
                })
            }
            console.log(`请求 - 结束`, re.data)
            return re.data
        }
        if (loading) {
            controls.loading.show({ mask: true, title: '请稍候' })
        }
        try {
            let re = await handle(path, data)
            if (loading) {
                controls.loading.hide()
            }
            return re
        } catch (error) {
            if (loading) {
                controls.loading.hide()
            }
            return {
                status: 0,
                content: `${error}`
            }
        }
    },
    selectFiles(maxFiles = -1) {
        return new Promise((resolve, reject) => {
            const input = document.createElement('input');
            input.type = 'file';
            input.multiple = true;
            input.onchange = async (event) => {
                const files = Array.from(event.target.files);
                if (maxFiles != -1 && files.length > maxFiles) {
                    return reject(new Error(`你最多只能选择${maxFiles}个文件`));
                }
                const fileInfoPromises = files.map(async file => {
                    const fileData = await getFileData(file);
                    return {
                        name: file.name,
                        path: file.webkitRelativePath || file.name,
                        size: file.size,
                        createdAt: file.lastModifiedDate,  // 浏览器无法获取创建时间，只能获取最后修改时间
                        updatedAt: file.lastModifiedDate,
                        extension: getFileExtension(file.name),
                        baseName: getBaseName(file.name),
                        data: fileData
                    };
                });
                const fileInfoArray = await Promise.all(fileInfoPromises);
                resolve(fileInfoArray);
            };
            input.click();
        });
    },
    Object: {
        assign(o1, o2) {
            return Object.assign(JSON.parse(JSON.stringify(o1)), o2)
        }
    },
    controls,
    routerf() {
        return useRouter()
    },
    setTimeout: setTimeout,
    localStorage: {
        setItem(key, value) {
            let type = ''
            if (value instanceof Date) {
                type = 'date'
                value = value.getTime()
            } else if (value === undefined) {
                type = 'undefined'
                value = 'undefined'
            } else if (value === null) {
                type = 'null'
                value = 'null'
            } else {
                type = 'other'
            }
            value = JSON.stringify(value)
            localStorage.setItem(key, JSON.stringify({
                type,
                value
            }))
        },
        getItem(key) {
            let value = localStorage.getItem(key)
            if (value === null) return null
            value = JSON.parse(value)
            if (value.type === 'undefined') return undefined
            if (value.type === 'null') return null
            if (value.type === 'date') return new Date(value.value)
            return JSON.parse(value.value)
        },
        removeItem(key) {
            localStorage.removeItem(key)
        }
    },
    router: {
        push: (path) => {
            store.setItem('router_push', path)
        }
    },
    debounce(func, wait = 300) {
        let timeout;
        return function (...args) {
            const later = () => {
                clearTimeout(timeout);
                func.apply(this, args);
            };

            clearTimeout(timeout);
            timeout = setTimeout(later, wait);
        };
    },
    focusElementById(elementId) {
        const element = document.getElementById(elementId);
        if (element) {
            element.focus();
        } else {
            // console.error(`Element with ID ${elementId} not found.`);
        }
    },
    getRPXFunction() {
        let zoom = ref(1)
        store.onChange('zoom', (e) => zoom.value = e)
        return (n, num = false) => {
            if (num) {
                return n * zoom.value
            } else {
                return `${n * zoom.value}px`
            }
        }
    },
    getIsMobileFunction() {
        let is = ref(true)
        store.onChange('isMobile', (e) => {
            is.value = e
        })
        return () => is.value
    },
    async flow(fn = () => { }, errorHandler = () => { }) {
        try {
            let re = await fn()
            return re
        } catch (error) {
            await errorHandler(error)
        }
    },
    scrollToBottom(elementId) {
        // 获取指定 ID 的元素
        const element = document.getElementById(elementId);

        if (element) {
            // 使用 scrollTop 和 scrollHeight 滚动到底部
            element.scrollTop = element.scrollHeight;
        } else {
            console.error(`未找到 ID 为 "${elementId}" 的元素`);
        }
    },
    isRangeRepeat(start1, end1, start2, end2) {
        if (start1 > end1) throw '第一个范围格式错误'
        if (start2 > end2) throw '第二个范围格式错误'
        if (start2 <= end1 && start2 >= start1) throw '范围重复'
        if (start1 <= end2 && start1 >= start2) throw '范围重复'
    },
    async requestStream(path = '', data = {}, method = 'post', loading = true, onData) {
        method = method.toLowerCase();

        const handle = async (url, data) => {
            console.log(`请求 - 开始`, path, method, data);

            const fetchUrl = config.apiPrefix + url + (method === 'get' ? `?${qs.stringify(data)}` : '');

            const res = await fetch(fetchUrl, {
                method: method.toUpperCase(),
                headers: {
                    'Content-Type': 'application/json',
                },
                body: method === 'post' ? JSON.stringify(data) : undefined,
            });

            console.log(res.body)

            if (!res.ok || !res.body) {
                throw new Error(`请求失败，状态码：${res.status}`);
            }

            const reader = res.body.getReader();
            const decoder = new TextDecoder('utf-8');
            let fullText = '';

            while (true) {
                const { done, value } = await reader.read();
                if (done) break;

                const chunk = decoder.decode(value, { stream: true });
                fullText += chunk;

                if (typeof onData === 'function') {
                    onData(chunk); // 中间数据流返回
                }
            }

            console.log(`请求 - 结束`, fullText);
            return {
                status: 1,
                content: fullText,
            };
        };

        if (loading) {
            controls.loading.show({ mask: true, title: '请稍候' });
        }

        try {
            const re = await handle(path, data);
            if (loading) {
                controls.loading.hide();
            }
            return re;
        } catch (error) {
            if (loading) {
                controls.loading.hide();
            }
            return {
                status: 0,
                content: `${error}`,
            };
        }
    },
    splitJsonObjects(str) {
        const objects = [];
        let start = 0;
        let braceCount = 0;

        for (let i = 0; i < str.length; i++) {
            const char = str[i];

            if (char === '{') {
                if (braceCount === 0) start = i;
                braceCount++;
            } else if (char === '}') {
                braceCount--;
                if (braceCount === 0) {
                    const jsonStr = str.slice(start, i + 1);
                    try {
                        const obj = JSON.parse(jsonStr);
                        objects.push(obj);
                    } catch (e) {
                        console.error('JSON解析失败:', jsonStr, e);
                    }
                }
            }
        }

        return objects;
    },
    getThemeColor(themeName, defaultColor = 'red') {
        let isDarkMode = this.getIsDarkModeFunction()
        let theme = JSON.parse(JSON.stringify(config.theme))
        themeName = themeName.split('.')
        for (let i = 0; i < themeName.length; i++) {
            theme = theme[themeName[i]]
            if (theme === undefined) {
                return defaultColor
            }
        }
        theme = theme[isDarkMode() ? 'd' : 'l']
        if (theme === undefined) return defaultColor
        return theme
    },
    getIsDarkModeFunction() {
        let darkMode = ref(store.getItem('darkMode'))
        store.onChange('darkMode', (e) => {
            darkMode.value = e
        })
        return () => {
            return darkMode.value === true
        }
    },
    addTopTitleToArr(re) {
        for (let i = 0; i < re.length; i++) {
            delete re[i].topTitle
            if (!i || this.formatDateString(re[i].createdAt) != this.formatDateString(re[i - 1].createdAt)) {
                re[i].topTitle = this.formatDateString(re[i].createdAt)
            }
        }
        return re
    },
    scrollToBottomById(id) {
        const el = document.getElementById(id);
        if (el) {
            el.scrollTop = el.scrollHeight;
        } else {
            console.warn(`元素ID为 "${id}" 的节点不存在。`);
        }
    },
    formatDateString(inputDate) {
        const date = new Date(inputDate);
        const now = new Date();
        const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
        const target = new Date(date.getFullYear(), date.getMonth(), date.getDate());
        const diffDays = Math.round((target - today) / (1000 * 60 * 60 * 24));

        if (diffDays === 2) return "后天";
        if (diffDays === 1) return "明天";
        if (diffDays === 0) return "今天";
        if (diffDays === -1) return "昨天";
        if (diffDays === -2) return "前天";

        const weekdays = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"];
        const targetWeekday = weekdays[date.getDay()];

        const oneWeekAgo = new Date();
        oneWeekAgo.setDate(today.getDate() - 7);

        const oneWeekLater = new Date();
        oneWeekLater.setDate(today.getDate() + 7);

        // if (target <= oneWeekAgo && target < today) return `上${targetWeekday}`;
        // if (target > today && target <= oneWeekLater) return targetWeekday;

        const year = date.getFullYear();
        const month = date.getMonth() + 1;
        const day = date.getDate();

        if (year === now.getFullYear()) {
            return `${month}月${day}日`;
        } else {
            return `${year}年${month}月${day}日`;
        }
    },
    scrollElementToTop(containerId, targetId) {
        const container = document.getElementById(containerId);
        const target = document.getElementById(targetId);

        if (container && target) {
            const offsetTop = target.offsetTop;
            container.scrollTop = offsetTop - target.clientHeight;
        } else {
            console.warn('容器或目标元素不存在');
        }
    },
    formatTimeNew(inputTime = new Date()) {
        function getPeriod(hours) {
            if (hours >= 0 && hours < 6) {
                return '凌晨';
            } else if (hours >= 6 && hours < 11) {
                return '上午';
            } else if (hours >= 11 && hours < 14) {
                return '中午';
            } else if (hours >= 14 && hours < 18) {
                return '下午';
            } else {
                return '晚上';
            }
        }

        function getWeekName(n) {
            switch (n) {
                case 0:
                    return '星期天'
                case 1:
                    return '星期一'
                case 2:
                    return '星期二'
                case 3:
                    return '星期三'
                case 4:
                    return '星期四'
                case 5:
                    return '星期五'
                case 6:
                    return '星期六'
            }
        }
        let currentTime = new Date()
        let oneDaySecond = 86400000
        let currentDayStart = new Date(currentTime.getTime() - currentTime.getHours() * 60 * 60 * 1000 - currentTime
            .getMinutes() * 60 * 1000 - currentTime.getSeconds() * 1000)
        let lastDayStart = new Date(currentTime.getTime() - currentTime.getHours() * 60 * 60 * 1000 - currentTime
            .getMinutes() * 60 * 1000 - currentTime.getSeconds() * 1000 - oneDaySecond)
        let nextDayStart = new Date(currentTime.getTime() - currentTime.getHours() * 60 * 60 * 1000 - currentTime
            .getMinutes() * 60 * 1000 - currentTime.getSeconds() * 1000 + oneDaySecond)
        let nextDayEnd = new Date(currentTime.getTime() - currentTime.getHours() * 60 * 60 * 1000 - currentTime
            .getMinutes() * 60 * 1000 - currentTime.getSeconds() * 1000 + oneDaySecond * 2)
        let prefix = ''
        if (inputTime >= currentDayStart && inputTime < nextDayStart) {
            prefix = '今天'
        }
        if (inputTime >= lastDayStart && inputTime < currentDayStart) {
            prefix = '昨天'
        }
        if (inputTime >= nextDayStart && inputTime < nextDayEnd) {
            prefix = '明天'
        }
        if (prefix == '') {
            prefix = (inputTime.getFullYear() == currentTime.getFullYear() ? '' : inputTime.getFullYear().toString() +
                '年') + (inputTime.getMonth() + 1).toString() + '月' + inputTime.getDate() + '日 '
        }
        prefix += getPeriod(inputTime.getHours()) + ' '
        prefix += inputTime.getHours().toString() + ':'
        if (inputTime.getMinutes() < 10) {
            prefix += '0'
        }
        prefix += inputTime.getMinutes().toString() + ' '
        prefix += getWeekName(inputTime.getDay())
        return prefix
    },
}


function getFileExtension(fileName) {
    return fileName.split('.').pop();
}

function getBaseName(fileName) {
    return fileName.substring(0, fileName.lastIndexOf('.')) || fileName;
}

function getFileData(file) {
    return new Promise((resolve) => {
        const reader = new FileReader();
        reader.onload = () => {
            const blobURL = URL.createObjectURL(new Blob([reader.result]));
            const formData = new FormData();
            formData.append('file', file);
            resolve({
                blobURL,
                file,
                formData
            });
        };
        reader.readAsArrayBuffer(file);
    });
}